﻿using BasicData.API.Application.Command;
using BasicData.API.Dtos;
using BasicData.API.Services;
using BasicData.Domain.Entities;
using BasicData.ErrorCode;
using BasicData.Infrastructure.Interfasce;
using MediatR;
using Microsoft.EntityFrameworkCore;

namespace BasicData.API.Application.CommandHandlers
{
    /// <summary>
    /// 登录查询命令处理器
    /// </summary>
    public class LoginQueryCommandHandler : IRequestHandler<LoginQueryCommand, APIResult<UserDTO>>
    {
        private readonly IBaseRepositroy<User> _userRepository;
        private readonly IBaseRepositroy<Role> roleRepository;
        private readonly IBaseRepositroy<UserRole> userRoleRepository;
        private readonly JwtHelper jwtHelper;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="userRepository">用户仓储</param>
        /// <param name="roleRepository">角色仓储</param>
        /// <param name="userRoleRepository">用户角色仓储</param>
        /// <param name="jwtHelper">JWT辅助类</param>
        public LoginQueryCommandHandler(
            IBaseRepositroy<User> userRepository,
            IBaseRepositroy<Role> roleRepository,
            IBaseRepositroy<UserRole> userRoleRepository,
            JwtHelper jwtHelper)
        {
            _userRepository = userRepository;
            this.roleRepository = roleRepository;
            this.userRoleRepository = userRoleRepository;
            this.jwtHelper = jwtHelper;
        }

        /// <summary>
        /// 处理登录查询命令
        /// </summary>
        /// <param name="request">登录查询命令</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>登录结果</returns>
        public async Task<APIResult<UserDTO>> Handle(LoginQueryCommand request, CancellationToken cancellationToken)
        {
            try
            {
                // 查询用户
                var user = await _userRepository.FirstOrDefaultAsync(x => x.Username == request.Username && x.Password == request.Password)
                    .FirstOrDefaultAsync(cancellationToken);

                // 验证用户是否存在
                if (user == null)
                {
                    return new APIResult<UserDTO>
                    {
                        Code = ResultCode.用户名或密码错误,
                        Message = "用户名或密码错误",
                        Data = null
                    };
                }

                // 验证用户状态
                if (user.Status == 0)
                {
                    return new APIResult<UserDTO>
                    {
                        Code = ResultCode.用户被禁用,
                        Message = "用户已被禁用",
                        Data = null
                    };
                }

                // 获取用户角色
                var userRole = await userRoleRepository.FirstOrDefaultAsync(x => x.UserId == user.UserId)
                    .FirstOrDefaultAsync(cancellationToken);
                
                var role = userRole != null 
                    ? await roleRepository.FirstOrDefaultAsync(x => x.RoleId == userRole.RoleId).FirstOrDefaultAsync(cancellationToken) 
                    : null;

                // 生成JWT令牌
                string token = jwtHelper.GenerateToken(
                    user.UserId,
                    user.RealName,
                    role?.RoleId ?? 0,
                    role?.RoleName ?? string.Empty
                );

                // 构建返回对象
                var userDto = new UserDTO
                {
                    UserId = user.UserId,
                    Username = user.Username,
                    Password = string.Empty, // 不返回密码
                    RealName = user.RealName,
                    Status = user.Status,
                    RoleId = role?.RoleId ?? 0,
                    RoleName = role?.RoleName ?? string.Empty,
                    Token = token
                };

                return new APIResult<UserDTO>
                {
                    Code = ResultCode.登录成功,
                    Message = "登录成功",
                    Data = userDto
                };
            }
            catch (Exception ex)
            {
                return new APIResult<UserDTO>
                {
                    Code = ResultCode.登录失败,
                    Message = $"登录失败: {ex.Message}",
                    Data = null
                };
            }
        }
    }
} 